package org.fnzn.service.base;

import java.lang.reflect.Field;
import java.lang.reflect.ParameterizedType;
import java.util.List;
import java.util.Map;

import org.apache.ibatis.exceptions.TooManyResultsException;
import org.fnzn.common.MyMapper;
import org.fnzn.core.Query;
import org.fnzn.core.TableResultResponse;
import org.fnzn.exception.MyException;
import org.fnzn.util.DateTools;
import org.springframework.beans.factory.annotation.Autowired;

import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;

import tk.mybatis.mapper.entity.Condition;
import tk.mybatis.mapper.entity.Example;



public abstract class AbstractService<T> implements Service<T> {
	@Autowired
    protected MyMapper<T> myMapper;

    private Class<T> modelClass;    // 当前泛型真实类型的Class

    @SuppressWarnings("unchecked")
	public AbstractService() {
        ParameterizedType pt = (ParameterizedType) this.getClass().getGenericSuperclass();
        modelClass = (Class<T>) pt.getActualTypeArguments()[0];
    }

    @Override
    public int save(T model) {   //保存实体
    	addValue(model,true);
        return myMapper.insertSelective(model);
    }
    @Override
    public int save(List<T> models) {//批量保存    要求id为自增主键
    	 return myMapper.insertList(models);
    }

    @Override
    public int deleteById(Object id) {//通过主键删除
    	return myMapper.deleteByPrimaryKey(id);
    }
    @Override
    public int deleteByCondition(Condition condition) {
    	return myMapper.deleteByExample(condition);
    }

    @Override
    public int update(T model) {//更新实体    实体传什么属性就更新什么属性  不更新空值
    	addValue(model,false);
    	return myMapper.updateByPrimaryKeySelective(model);
    }
    
    @SuppressWarnings("unchecked")
	@Override
    public TableResultResponse<T> findByQuery(Query query){
		Class<T> clazz = (Class<T>) ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0];
        Example example = new Example(clazz);
        if(query.entrySet().size()>0) {
            Example.Criteria criteria = example.createCriteria();
            for (Map.Entry<String, Object> entry : query.entrySet()) {
                criteria.andLike(entry.getKey(), "%" + entry.getValue().toString() + "%");
            }
        }
        Page<Object> result = PageHelper.startPage(query.getPage(), query.getLimit());
        List<T> list = myMapper.selectByExample(example);
        return new TableResultResponse<T>(result.getTotal(), list);
    }
    @Override 
    public List<T> find(T record){
    	return myMapper.select(record);
    }
    @Override 
    public T findOne(T record){
    	return myMapper.selectOne(record);
    }

    @Override
    public T findById(Object id) {//通过主键查找
        return myMapper.selectByPrimaryKey(id);
    }

    @Override
    public T findBy(String property, Object value) throws TooManyResultsException {//通过属性查找   要求结果唯一
        try {
            T model = modelClass.newInstance();
            Field field = modelClass.getDeclaredField(property);
            field.setAccessible(true);
            field.set(model, value);
            return myMapper.selectOne(model);
        } catch (ReflectiveOperationException e) {
            throw new MyException(e.getMessage());
        }
    }

    

    @Override
    public List<T> findByCondition(Condition condition) { //条件查找
        return myMapper.selectByExample(condition);
    }

    @Override
    public List<T> findAll() {//全量查找
        return myMapper.selectAll();
    }
    /**
     * 通用注入创建 更新信息 可通过super调用
     * @param record
     * @param flag
     * @return
     */
    public T  addValue(T record,boolean flag){
      //统一处理公共字段
      try {
        if(flag){
          Field fieldDate=modelClass.getDeclaredField("crtDate");
          if(fieldDate!=null){
  	        fieldDate.setAccessible(true);
  	        fieldDate.set(record, DateTools.getCurrentSysData(DateTools.DEFAULT_FORMAT));
          }
          Field fieldDate2=modelClass.getDeclaredField("mtnDate");
          if(fieldDate2!=null){
    	        fieldDate2.setAccessible(true);
    	        fieldDate2.set(record,DateTools.getCurrentSysData(DateTools.DEFAULT_FORMAT));
          }
        }else{
          Field fieldDate=modelClass.getDeclaredField("mtnDate");
          if(fieldDate!=null){
  	        fieldDate.setAccessible(true);
  	        fieldDate.set(record,DateTools.getCurrentSysData(DateTools.DEFAULT_FORMAT));
          }
        }
      } catch (NoSuchFieldException e) {
        //无此字段
      } catch (IllegalAccessException e) {
        e.printStackTrace();
      }
      return record;
    }

}
